package com.bean;


/**
 * @author Cc
 * 2024-04-01
 */
public class SenTrueList<E> {
    /**
     * 集合的实际大小
     */
    private int size;
    /**
     * ArrayList集合实际是对数组进行封装 - 动态数组
     */
    private Object[] elementData;

    /**
     * 数组默认容量 - 每次添加元素之前，都需要判断容量，按需进行扩容
     */
    private static final int DEFAULT_CAPACITY = 3;

    /**
     * 缺省（默认）构造方法
     */
    public SenTrueList() {
        elementData = new Object[DEFAULT_CAPACITY];
    }

    /**
     * 重载构造方法 - 用户指定数组的容量
     *
     * @param size
     */
    public SenTrueList(int size) {
        elementData = new Object[size];
    }

    /**
     * 添加元素
     *
     * @param e
     * @return
     */
    public boolean add(E e) {
        // 判断数组容量是否充足，不充足需要动态扩容
        ensureCapacityInternal();

        // 添加元素，size加1
        this.elementData[size++] = e;
        // size++
        return true;
    }

    /**
     * 实现数组动态扩容
     */
    private void ensureCapacityInternal() {
        if (size >= elementData.length) {
            // 1.动态扩容 - 原来长度 * 2
            Object[] newArr = new Object[elementData.length * 2];

            // 2.复制原数组的数据
            System.arraycopy(elementData, 0, newArr, 0, elementData.length);

            elementData = newArr;
        }
    }

    public Object[] getElementData() {
        return this.elementData;
    }

    /**
     * 删除元素
     *
     * @param index
     * @return
     */
    public E remove(int index) {
        // 1.检查下标索引是否越界
        rangeCheck(index);

        // 2.获取删除的元素
        E oldValue = (E) elementData[index];

        // 3.判断删除元素的位置
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index + 1, elementData, index,
                    numMoved);
        elementData[--size] = null; // clear to let GC do its work

        // 4.返回删除的元素
        return oldValue;
    }

    /**
     * 返回集合元素的实际个数
     *
     * @return
     */
    public int size() {
        return this.size;
    }

    /**
     * 给集合某个下标设置元素
     *
     * @param index
     * @param element
     * @return
     */
    public E set(int index, E element) {
        // 1.检查下标索引是否越界
        rangeCheck(index);

        // 2.获取被覆盖的元素
        E oldValue = (E) elementData[index];

        // 3.覆盖下标索引对应的元素
        elementData[index] = element;

        // 4.返回被覆盖的元素
        return oldValue;
    }

    /**
     * 获取集合下标对应的元素
     *
     * @param index 下标
     * @return 下标对应的元素
     */
    public E get(int index) {
        // 检查下标索引是否越界
        rangeCheck(index);

        return (E) elementData[index];
    }

    /**
     * 检查下标合法性 -- 封装方法
     * 1）复用
     * 2）单一职责原则
     *
     * @param index
     */
    private void rangeCheck(int index) {
        if (index < 0 || index >= elementData.length) {
            throw new RuntimeException("数组下标索引越界");
        }
    }

    /**
     * 判断集合是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return size == 0;
    }
}
